#include "scc/MatchInfo.h"
#include "base/Processor.h"
#include "base/SnoopRequest.h"

NEW_DELETE_OPERATORS_CPP(MatchInfo,10);

const char* MatchFlagStrings[] = {
    "MATCH_INPUT_BUFFER",
    "MATCH_CACHE_HASH",
    "MATCH_MSHR",
    "MATCH_OUTPUT_BUFFER",
    "MATCH_OVERFLOW_MANAGER"
};

MatchInfo::MatchInfo (MatchFlag _flag,
                      Request* _r,
                      MESICache* _location) :
    flag(_flag),
    location(_location),
    matchingEntry(NULL),
    dataRequest(NULL),
    internalRequest(_r)
{
}


MatchInfo::MatchInfo (MatchFlag _flag,
                      Request* _r,
                      MESICache* _location,
                      DataRequest* _dataRequest) :
    flag(_flag),
    location(_location),
    dataRequest(_dataRequest),
    internalRequest(_r)
{
    matchingEntry = NULL;
}
              
MatchInfo::MatchInfo (MatchFlag _flag,
                      Request* _r,
                      MESICache* _location,
                      DataRequest* dr,
                      CacheEntry* _matchingEntry) :                     
    flag(_flag),
    location(_location),
    matchingEntry(_matchingEntry),
    dataRequest(dr),
    internalRequest(_r)
{ }

const char* MatchInfo::getFlagName () {
    return MatchFlagStrings[flag];
}

MatchFlag MatchInfo::getFlag () {
    return flag;
}

MESICache* MatchInfo::getLocation () {
    return location;
}

CacheEntry* MatchInfo::getMatchingEntry () {
    return matchingEntry;
}

DataRequest* MatchInfo::getDataRequest () {
    return dataRequest;
}

Request* MatchInfo::getInternalRequest () {
    return internalRequest;
}

bool MatchInfo::isFromOverflowManager() {
    return flag == MATCH_OVERFLOW_MANAGER;
}

Processor* MatchInfo::getRequester() {
    SnoopRequest* snr = CAST_OR_DIE(SnoopRequest*, internalRequest);
    DataRequest* dr = CAST_OR_DIE(DataRequest*, snr->getPacket());
    return dr->getProcessor();
}

VA MatchInfo::getAddr() {
    SnoopRequest* snr = CAST_OR_DIE(SnoopRequest*, internalRequest);
    DataRequest* dr = CAST_OR_DIE(DataRequest*, snr->getPacket());
    return dr->getAddress();
}
